#include "fig_bone_object.h"
#include "fighter.h"
#include "fig_sfx.h"
#include "fig_sfx_manager.h"
  
#include "num/rand.h"
#include "script/scripthelper.h"

using namespace script;

FIGBoneObject::FIGBoneObject() : 
				FIGBoneAnimation(),
				m_ExpldoingCounter(0)								 
{
	m_Pos = math::Vec2(-1.0f,-1.0f);			// offscreen first before it got initialized
	m_Color = ColorfRGBA(1.0f,1.0f,1.0f,1.0f);
	m_ExpldoingCounter = 0;
}

void	FIGBoneObject::ExplodingInfo::Reset()
{
				
	m_RandomMovePos = math::Vec2(0,0);
	m_RandomDir = math::Vec2(0,0);
	m_Alpha = 1.0f;
	m_RotationSpeed = 1.0f;
	m_Scale = 1.0f;
	m_Rotation = 0.0f;
	m_Counter = 0;
	

	if(m_pSFX_ExploeSmoke)
	{
		m_pSFX_ExploeSmoke->ToDie();
		m_pSFX_ExploeSmoke = NULL;
	}
		
}


void		FIGBoneObject::Render(const math::Vec2& Offset,float Scale)
{
	
	if(!IsExploding())
	{
		FIGBoneAnimation::Render(Offset,Scale);
		return;
	}

	if( (int)m_AnimatinSteps.size() - 1 < m_CurrentStep)
		return;

	FIGBoneAnimation::AnimationStep* pAnimationStep = m_AnimatinSteps[m_CurrentStep];
	
	for(int i = 0; i < (int)pAnimationStep->m_pAnimationParts.size(); i++)
	{
		FIGBoneAnimation::AnimatonPart* pAnimationPart = pAnimationStep->m_pAnimationParts[i];
		if(pAnimationPart->m_pBonePart == NULL)
			continue;

		FIGBonePart* pBodyPart = pAnimationPart->m_pBonePart;
		math::Vec2 Pos = m_Pos +  Offset + m_ExplodingInfos[i]->m_RandomMovePos;
		float Rotation = m_Rotation + m_ExplodingInfos[i]->m_Rotation;
		COLOR c =  ColorfRGBA( 0.6f,0.6f,0.6f,m_ExplodingInfos[i]->m_Alpha);
			
		if(IsExploding() && m_ExplodingInfos[i]->m_Alpha > 0 && pBodyPart->IsOkToExplode() )
		{
			if(m_ExplodingInfos[i]->m_pSFX_ExploeSmoke)
			{
				m_ExplodingInfos[i]->m_pSFX_ExploeSmoke->FollowMe(Pos);
				m_ExplodingInfos[i]->m_pSFX_ExploeSmoke->SetSkipDrawing(false);
				m_ExplodingInfos[i]->m_pSFX_ExploeSmoke->Render(Offset,Scale);
				m_ExplodingInfos[i]->m_pSFX_ExploeSmoke->SetSkipDrawing(true);
			}
		}

		if(!IsExploding())
		{
			pBodyPart->Render(Pos,Scale,Rotation, c);
		}
		else
		{
			if( m_ExplodingInfos[i]->m_Alpha > 0 && pBodyPart->IsOkToExplode() && m_ExplodingInfos[i]->m_Scale )
				pBodyPart->Render(Pos,Scale * m_ExplodingInfos[i]->m_Scale ,Rotation, c);	
		}
	}   
}

FIGBoneObject::~FIGBoneObject()
{
	for(int i = 0; i < (int)m_ExplodingInfos.size(); i++)
	{
		UTIL_SAFE_DELETE(m_ExplodingInfos[i]);
	}
	m_ExplodingInfos.resize(0);
	 
}



void		FIGBoneObject::RenderShadow(const math::Vec2& Offset,float Scale)
{
	FIGBoneAnimation::RenderShadow(Offset,Scale);
	
}



void	FIGBoneObject::Tick(float dt)
{
	
	if(m_ExpldoingCounter > 0)
	{
		m_ExpldoingCounter -= dt;
		for(int i = 0; i < (int)m_ExplodingInfos.size(); i++)
		{
			FIGBoneObject::ExplodingInfo* pExplodingInfo = m_ExplodingInfos[i];
			pExplodingInfo->m_Rotation += (pExplodingInfo->m_RotationSpeed * dt);
			pExplodingInfo->m_RandomMovePos += (pExplodingInfo->m_RandomDir * dt);

			if(pExplodingInfo->m_Alpha >= 0.5f)
				pExplodingInfo->m_Alpha -= ( dt * 0.25f);
			if(pExplodingInfo->m_Scale > 0.5f)
				pExplodingInfo->m_Scale -= (dt);

			pExplodingInfo->m_Counter -= dt;

			if(pExplodingInfo->m_Counter <= 0 || pExplodingInfo->m_Scale <= 0  )
			{
				pExplodingInfo->m_Alpha = 0;		// dun show
				if(pExplodingInfo->m_pSFX_ExploeSmoke)
				{
					pExplodingInfo->m_pSFX_ExploeSmoke->ToDie();
					pExplodingInfo->m_pSFX_ExploeSmoke = NULL;
				}
			}
		}	

		
	}

	if( (int)m_AnimatinSteps.size() - 1 < m_CurrentStep)
		return;

	FIGBoneAnimation::AnimationStep* pAnimationStep = m_AnimatinSteps[m_CurrentStep];
	if(pAnimationStep)
	{
		for(int i = 0; i < (int)pAnimationStep->m_pAnimationParts.size(); i++)
		{
			FIGBoneAnimation::AnimatonPart* pAnimationPart = pAnimationStep->m_pAnimationParts[i];
			if(pAnimationPart->m_pBonePart == NULL)
				continue;

			FIGBonePart* pBodyPart = pAnimationPart->m_pBonePart;
			pBodyPart->Tick(dt);
		}
	}

}

void	FIGBoneObject::Explode(FIGLifeObj* pOwner)
{
	const float EXPLODING_TIME = 1.0f;
	m_ExpldoingCounter = EXPLODING_TIME; 

	for(int i = 0; i < (int)m_ExplodingInfos.size(); i++)
	{
		FIGBoneObject::ExplodingInfo* pExplodingInfo = m_ExplodingInfos[i];
		pExplodingInfo->Reset();

		int RandVal = num::RAND32::Instance().RandInt(1,3);
		if(RandVal == 1)
		{
			pExplodingInfo->m_pSFX_ExploeSmoke = FIGSFXManager::Instance().Spawn(
										FIGSfx::EXPLODING_BONESMOKE,
										m_Pos,
										1.0f);
			pExplodingInfo->m_pSFX_ExploeSmoke->SetSkipDrawing(true);

		}
		if(RandVal == 2)
		{
			pExplodingInfo->m_pSFX_ExploeSmoke = FIGSFXManager::Instance().Spawn(
										FIGSfx::EXPLODING_TYPE_EXPLODEBANG,
										m_Pos,
										0.35f);

			pExplodingInfo->m_pSFX_ExploeSmoke = FIGSFXManager::Instance().Spawn(
										FIGSfx::EXPLODING_TYPE_AFTEREXPLODE,
										m_Pos,
										0.35f);
			pExplodingInfo->m_pSFX_ExploeSmoke->SetSkipDrawing(true);

		}

		pExplodingInfo->m_Counter = num::RAND32::Instance().RandFloat( EXPLODING_TIME * 0.5f , EXPLODING_TIME);
		pExplodingInfo->m_RotationSpeed =  num::RAND32::Instance().RandFloat( 300.0f,400.0f);
		if(num::RAND32::Instance().RandInt(0,1) == 0)
			pExplodingInfo->m_RotationSpeed  *= -1;

		pExplodingInfo->m_RandomDir = math::Vec2(
								num::RAND32::Instance().RandFloat( -1.0f,1.0f),
								num::RAND32::Instance().RandFloat( -1.0f,1.0f));

		pExplodingInfo->m_RandomDir *= num::RAND32::Instance().RandFloat( 0.25f,0.4f);

		pExplodingInfo->m_Alpha = 1.0f;

		
	}
}


math::Vec2		FIGBoneObject::Load(const std::string& File)
{
	math::Vec2 RetunVal = FIGBoneAnimation::Load(File);

	for(int i = 0; i < (int)m_BoneParts.size(); i++)
	{
		m_ExplodingInfos.push_back(new FIGBoneObject::ExplodingInfo());
	}

	return RetunVal;
}

bool		FIGBoneObject::HitTest(const math::Vec2& Pos)
{
	if( (int)m_AnimatinSteps.size() - 1 < m_CurrentStep)
		return false;
	FIGBoneAnimation::AnimationStep* pAnimationStep = m_AnimatinSteps[m_CurrentStep];
	
  	for(int i = 0; i < (int)pAnimationStep->m_pAnimationParts.size(); i++)
	{
		FIGBoneAnimation::AnimatonPart* pAnimationPart = pAnimationStep->m_pAnimationParts[i];
		if(pAnimationPart->m_pBonePart == NULL)
			continue;

		FIGBonePart* pBodyPart = pAnimationPart->m_pBonePart;
		bool b = pBodyPart->HitTest(m_Pos, Pos);
		if(b)
			return true;
	}

	return false;
}




